package cn.bluethink.eguan.core.util;

import java.util.Date;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;

/**
 * 钉钉登录工具类
 * 
 * @title 苏州中科蓝迪公司所有(c)2016-2021
 * @version 0.1.0
 * @describe
 * @author liuxn
 * @note 修订历史： （1）liuxn于2018年8月17日构建初始版本0.1 
 * 				 （2）liuxn于2018年10月08日移除获取用户信息  getUserInfo 方法 
 * 				 （3）liuxn于2018年10月08日移除获取getAppAccesstoken 方法 
 *              （4）liuxn于2018年10月09日修订getUserPrincipal方法，返回类型调整为 EgUserEntity
 *              （5）giszyj@126.com于2018年10月10日修订整个DingUtil类
 */
@Component
public class DingUtil {
	public class DingUser {
		private String persistentCode;
		private String openId;
		private String unionId;
		private String nick;
		private String avatar;
		private String corpId;
		private String corpName;

		public DingUser(String persistentCode, String openId, String unionId, String nick, String avatar,String corpId,String corpName) {
			this.persistentCode = persistentCode;
			this.openId = openId;
			this.unionId = unionId;
			this.nick = nick;
			this.avatar = avatar;
			this.corpId = corpId;
			this.corpName = corpName;
		}

		public String persistentCode() {
			return persistentCode;
		}

		public String openId() {
			return openId;
		}

		public String unionId() {
			return unionId;
		}

		public String nick() {
			return nick;
		}
		public String avatar() {
			return avatar;
		}
		public String corpId() {
			return corpId;
		}

		public String corpName() {
			return corpName;
		}
		
	}

	@Value("${dingtalk.appid}")
	private String appid;

	@Value("${dingtalk.appsecret}")
	private String appsecret;

	private String accessToken = null; // 全局缓存，两个小时过期，需定时获取

	/**
	 * 每隔7100秒执行一次 获取获取accesstoken
	 */
	@Scheduled(fixedRate = 7140000,initialDelay = 0)
	public void excuteAccesstoken() {
		String url = "https://oapi.dingtalk.com/sns/gettoken?appid=" + appid + "&appsecret=" + appsecret;
		JSONObject json = ossHttpGetUtil(url);

		if (null != json) {
			if (Integer.parseInt(json.getString("errcode").toString()) == 0) {
				accessToken = json.getString("access_token");
				System.err.println(new Date());
			}
		}
	}

	/**
	 * 根据用户钉钉扫码获取的临时授权码获取钉钉用户个人信息
	 * @param code
	 * @return
	 */
	public DingUser getDingUser(String code) {
		if (accessToken == null)
			return null;
		// 获取用户授权的持久授权码
		JSONObject json = getPersistentCode(accessToken, code);
		if (json == null)
			return null;
		String openId = json.getString("openid");
		String persistentCode = json.getString("persistent_code");
		// 获取用户授权的SNS_TOKEN
		String snsToken = getSnsToken(accessToken, openId, persistentCode);
		if (snsToken == null)
			return null;
		// 获取用户个人信息
		JSONObject jsonUser = getUserInfo(snsToken);
		if (jsonUser == null)
			return null;
		String unionid = jsonUser.getString("unionid");
		String nick = jsonUser.getString("nick");

	//	return new DingUser(persistentCode, openId, unionid, nick,"", "ding_corp_id","中科蓝迪");
		return new DingUser(persistentCode, openId, unionid, nick,"", null, null);
	}

	/**
	 * 获取持久授权码persistent_code
	 * 
	 * @param accessToken
	 * @param code
	 * @return
	 */
	private JSONObject getPersistentCode(String accessToken, String code) {
		String url = "https://oapi.dingtalk.com/sns/get_persistent_code?access_token=" + accessToken;
		JSONObject jsonData = new JSONObject();
		jsonData.put("tmp_auth_code", code);
		JSONObject json = ossHttpPostUtil(url, jsonData);
		if (null != json) {
			if (Integer.parseInt(json.get("errcode").toString()) == 0) {
				return json;
			}
		}
		return null;
	}

	/**
	 * 获取SNS_TOKEN
	 * 
	 * @param accesstoken
	 * @param openid
	 * @param persistent_code
	 * @return
	 */
	private String getSnsToken(String accesstoken, String openid, String persistent_code) {
		String url = "https://oapi.dingtalk.com/sns/get_sns_token?access_token=" + accesstoken;

		JSONObject jsonData = new JSONObject();
		jsonData.put("openid", openid);
		jsonData.put("persistent_code", persistent_code);
		JSONObject json = ossHttpPostUtil(url, jsonData);
		if (null != json) {
			if (Integer.parseInt(json.get("errcode").toString()) == 0) {
				String snsToken = json.getString("sns_token");
				return snsToken;
			}
		}
		return null;
	}

	/**
	 * 获取钉钉用户信息
	 * 
	 * @param snsToken
	 * @return
	 */
	private JSONObject getUserInfo(String snsToken) {
		try {
			String url = "https://oapi.dingtalk.com/sns/getuserinfo?sns_token=" + snsToken;
			JSONObject json = ossHttpGetUtil(url);
			if (null != json) {
				if (Integer.parseInt(json.get("errcode").toString()) == 0) {
					return json.getJSONObject("user_info");
				}
			}
			return null;
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 用Apache的HTTPClient4.5完成HTTPGET请求
	 * 
	 * @param url
	 * @return
	 */
	private JSONObject ossHttpGetUtil(String url) {
		HttpGet httpGet = new HttpGet(url);
		HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
		HttpClient httpClient = httpClientBuilder.build();
		HttpResponse httpResponse = null;
		try {
			httpResponse = httpClient.execute(httpGet);
		} catch (Exception e) {
		}

		// 得到httpResponse的状态响应码
		int statusCode = httpResponse.getStatusLine().getStatusCode();

		if (statusCode == HttpStatus.SC_OK) {
			// 得到httpResponse的实体数据
			HttpEntity httpEntity = httpResponse.getEntity();
			if (httpEntity != null) {
				try {
					return JSONObject.parseObject(EntityUtils.toString(httpEntity));
				} catch (Exception e) {

				}
			}
		}
		return null;
	}

	/**
	 * 用Apache的HTTPClient4.5完成HTTPPOST请求
	 * 
	 * @param url
	 * @param json
	 * @return
	 */
	private JSONObject ossHttpPostUtil(String url, JSONObject json) {
		HttpPost httpPost = new HttpPost(url);
		HttpEntity httpEntity = null;
		httpEntity = new StringEntity(json.toString(), "UTF-8");
		httpPost.setEntity(httpEntity);
		HttpResponse httpResponse = null;
		HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
		HttpClient httpClient = httpClientBuilder.build();
		try {
			httpResponse = httpClient.execute(httpPost);
		} catch (Exception e) {

		}

		// 得到httpResponse的状态响应码
		int statusCode = httpResponse.getStatusLine().getStatusCode();
		if (statusCode == HttpStatus.SC_OK) {
			// 得到httpResponse的实体数据
			HttpEntity httpEntity2 = httpResponse.getEntity();
			if (httpEntity2 != null) {
				try {
					return JSONObject.parseObject(EntityUtils.toString(httpEntity2));
				} catch (Exception e) {

				}
			}
		}
		return null;
	}
	
}